package com.joysuch.wwyt.bp.service.impl;

import cn.zlg.common.util.CollectionUtils;
import com.google.common.collect.Lists;
import com.joysuch.wwyt.bp.bean.investigate.BpInvestigateStoreBean;
import com.joysuch.wwyt.bp.entity.investigate.BpInvestigateStore;
import com.joysuch.wwyt.bp.entity.investigate.BpInvestigateStoreDetail;
import com.joysuch.wwyt.bp.entity.investigate.BpSafeTableItem;
import com.joysuch.wwyt.bp.enums.SafeTableSourceTypes;
import com.joysuch.wwyt.bp.repository.BpInvestigateStoreDetailRepository;
import com.joysuch.wwyt.bp.repository.BpInvestigateStoreRepository;
import com.joysuch.wwyt.bp.repository.BpSafeTableItemDao;
import com.joysuch.wwyt.bp.service.BpInvestigateStoreDetailService;
import com.joysuch.wwyt.bp.service.BpInvestigateStoreService;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import javafx.util.Pair;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author ZhangDong
 * @Date 2020/3/25 10:48
 */
@Service
@Transactional
public class BpInvestigateStoreServiceImpl implements BpInvestigateStoreService {

    @Autowired
    private BpInvestigateStoreRepository storeRepository;
    @Autowired
    private BpInvestigateStoreDetailRepository detailRepository;
    @Autowired
    private BpInvestigateStoreDetailService storeDetailService;
    @Autowired
    private BpSafeTableItemDao safeTableItemDao;

    @Override
    public ResultBean save(BpInvestigateStoreBean bean) {
        Long id = bean.getId();
        String checkTypeName = bean.getCheckTypeName().trim();
        Long parentId = bean.getParentId();
        //同一级名称判重
        List<BpInvestigateStore> parentList = storeRepository.findByParentId(parentId);

        BpInvestigateStore bpInvestigateStore;
        if (id == null) {
            bpInvestigateStore = new BpInvestigateStore();
            if (!CollectionUtils.isEmpty(parentList)) {
                for (BpInvestigateStore investigateStore : parentList) {
                    if (checkTypeName.equals(investigateStore.getCheckTypeName())) {
                        return ResultBean.fail(101, "此排查类型名称已存在");
                    }
                }
            }
        } else {
            bpInvestigateStore = storeRepository.findById(id).orElseThrow(() -> new RuntimeException("修改的数据不存在"));
            if (!checkTypeName.equals(bpInvestigateStore.getCheckTypeName())) {
                if (!CollectionUtils.isEmpty(parentList)) {
                    for (BpInvestigateStore investigateStore : parentList) {
                        if (checkTypeName.equals(investigateStore.getCheckTypeName())) {
                            return ResultBean.fail(101, "此排查类型名称已存在");
                        }
                    }
                }
            }
        }
        BeanUtils.copyProperties(bean, bpInvestigateStore);
        //是否顶枝
        Pair<Boolean, Boolean> pair = topOrNot(parentId);
        if (!pair.getValue()) {
            return ResultBean.fail(101, "当前节点上不可继续新增");
        }
        if (bpInvestigateStore.getTopOrNot() == null) {
            bpInvestigateStore.setTopOrNot(pair.getKey());
        }
        bpInvestigateStore = storeRepository.save(bpInvestigateStore);
        //修改-做安全表项目的数据同步
        if (id != null) {
            List<BpInvestigateStoreDetail> detailList = detailRepository.findByStoreId(id);
            if (!org.springframework.util.CollectionUtils.isEmpty(detailList)) {
                List<Long> storeIdList = detailList.stream().map(r -> r.getId()).collect(Collectors.toList());
                List<BpSafeTableItem> itemList = safeTableItemDao.findBySourceAndSourceIdIn(SafeTableSourceTypes.HIDDEN_STORE, storeIdList);
                for (BpSafeTableItem item : itemList) {
                    item.setItem(bpInvestigateStore.getCheckTypeName());
                }
                safeTableItemDao.saveAll(itemList);
            }
        }

        return ResultBean.defaultSuccessResult();
    }

    @Override
    public ResultBean delete(Long id) {
        BpInvestigateStore investigateStore = storeRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("操作错误"));
        List<BpInvestigateStore> list = storeRepository.findByParentId(id);
        List<BpInvestigateStore> temp = Lists.newArrayList();
        for (BpInvestigateStore bpInvestigateStore : list) {
            List<BpInvestigateStore> tempList = storeRepository.findByParentId(bpInvestigateStore.getId());
            if (!CollectionUtils.isEmpty(tempList)) {
                temp.addAll(tempList);
            }
        }
        list.addAll(temp);
        list.add(investigateStore);
        //如果标准库下有检查标准不给删
        for (BpInvestigateStore store : list) {
            List<BpInvestigateStoreDetail> storeDetailList = detailRepository.findByStoreId(store.getId());
            if (!CollectionUtils.isEmpty(storeDetailList)) {
                return ResultBean.fail(101, "该排查标准库下有排查标准，请先删除排查标准！");
            }
        }
        for (BpInvestigateStore store : list) {
            storeRepository.deleteById(store.getId());
        }
        return ResultBean.defaultSuccessResult();
    }

    @Override
    public ResultBean list() {
        List<BpInvestigateStore> all = storeRepository.findAll();
        Map<Long, BpInvestigateStore> map = all.stream().collect(Collectors.toMap(BpInvestigateStore::getId, Function.identity()));
        for (BpInvestigateStore bpInvestigateStore : all) {
            Long parentId = bpInvestigateStore.getParentId();
            if (parentId != 0) {
                BpInvestigateStore temp = map.get(parentId);
                temp.getChildenSet().add(bpInvestigateStore);
            }
        }
        List<BpInvestigateStore> collect = all.stream().filter(r -> r.getParentId() == 0).collect(Collectors.toList());
        return ResultBean.success(collect);
    }

    @Override
    public ResultBean getByParentId(Long parentId) {
        return ResultBean.success(storeRepository.findByParentId(parentId));
    }

    @Override
    public String getNameById(Long storeId) {
        return  storeRepository.getNameById(storeId);
    }

    //k:topOrNot v:是否放行 false不放行
    private Pair<Boolean, Boolean> topOrNot(Long parentId) {
        int sum = 0;
        while (parentId != 0) {
            BpInvestigateStore bpInvestigateStore = storeRepository.findById(parentId).orElseThrow(() -> new RuntimeException("父节点不存在"));
            parentId = bpInvestigateStore.getParentId();
            sum++;
        }
        if (sum < 2) {
            return new Pair<>(false, true);
        }
        if (sum == 2) {
            return new Pair<>(true, true);
        }
        return new Pair<>(false, false);
    }
}
